package cn.uin.infrastructure.adapter.repository.common;

import cn.uin.domain.shared.adapter.repository.IPageable;
import cn.uin.domain.shared.adapter.repository.ISort;
import com.github.pagehelper.PageHelper;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.function.Supplier;

/**
 * @ClassName PageHelperAdapter
 * @Description:PageHelper 分页适配器
 *              封装 PageHelper 的使用，提供统一的分页执行接口
 * @Author: Administrator
 * @CreateDate: 2025/11/14 17:53
 * @Version: 1.0
 */
@Component
public class PageHelperAdapter {

	/**
	 * 执行分页查询
	 * @param pageable 分页参数
	 * @param querySupplier 查询供应商
	 * @param <T> 查询结果类型
	 * @return PageHelper 的 Page 对象
	 */
	public <T> com.github.pagehelper.Page<T> executeQuery(IPageable pageable, Supplier<List<T>> querySupplier) {
		// 如果不分页，直接执行查询
		if (!pageable.isPaged()) {
			List<T> result = querySupplier.get();
			return createUnpagedPage(result);
		}

		// 设置分页参数
		com.github.pagehelper.Page<T> page = PageHelper.startPage(
				pageable.getPageNumber() + 1, // PageHelper 页码从1开始
				pageable.getPageSize()
		);

		// 设置排序（如果存在）
		if (pageable.getSort().isSorted()) {
			String orderBy = convertSortToOrderBy(pageable.getSort());
			PageHelper.orderBy(orderBy);
		}

		try {
			// 执行查询
			querySupplier.get();
			return page;
		} finally {
			// 清理 ThreadLocal，防止内存泄漏
			PageHelper.clearPage();
		}
	}

	/**
	 * 将领域层的 Sort 对象转换为 PageHelper 的 orderBy 字符串
	 * @param sort 领域层排序对象
	 * @return PageHelper 可识别的 orderBy 字符串
	 */
	private String convertSortToOrderBy(ISort sort) {
		if (sort == null || !sort.isSorted()) {
			return "";
		}

		StringBuilder orderBy = new StringBuilder();
		for (ISort.Order order : sort.getOrders()) {
			if (orderBy.length() > 0) {
				orderBy.append(", ");
			}
			orderBy.append(camelToUnderline(order.getProperty()))
					.append(" ")
					.append(order.getDirection() == ISort.Direction.ASC ? "ASC" : "DESC");
		}

		return orderBy.toString();
	}

	/**
	 * 驼峰命名转下划线命名
	 * @param camelCase 驼峰命名字符串
	 * @return 下划线命名字符串
	 */
	private String camelToUnderline(String camelCase) {
		if (camelCase == null || camelCase.isEmpty()) {
			return camelCase;
		}

		StringBuilder result = new StringBuilder();
		for (int i = 0; i < camelCase.length(); i++) {
			char c = camelCase.charAt(i);
			if (Character.isUpperCase(c)) {
				if (i > 0) {
					result.append('_');
				}
				result.append(Character.toLowerCase(c));
			} else {
				result.append(c);
			}
		}
		return result.toString();
	}

	/**
	 * 创建不分页的 Page 对象
	 * @param content 数据内容
	 * @param <T> 数据类型
	 * @return PageHelper 的 Page 对象
	 */
	private <T> com.github.pagehelper.Page<T> createUnpagedPage(List<T> content) {
		com.github.pagehelper.Page<T> page = new com.github.pagehelper.Page<>(1, content.size());
		page.setTotal(content.size());
		page.addAll(content);
		return page;
	}

}
